package com.hexus.eve.utils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.JdbcUserDetailsManager;

import com.hexus.eve.entities.security.User;

public class HibernateUserDetailsService extends JdbcUserDetailsManager {

	private HibernateTemplate hibernateTemplate;
	
	
	@Override
	public UserDetails loadUserByUsername(String username)
		throws UsernameNotFoundException, DataAccessException {
		
		@SuppressWarnings("unchecked")
		List<User> users = getHibernateTemplate().find("from User where username = ?", new Object[] {username});

		if(users.size() == 0) {
			logger.debug("Query returned no results for user '" + username + "'");
			throw new UsernameNotFoundException(username + "not found");
		}

        User user = users.get(0);

        Set<GrantedAuthority> dbAuthsSet = new HashSet<GrantedAuthority>();

        if (getEnableAuthorities()) {
            dbAuthsSet.addAll(loadUserAuthorities(user.getUsername()));
        }

        if (getEnableGroups()) {
            dbAuthsSet.addAll(loadGroupAuthorities(user.getUsername()));
        }

        List<GrantedAuthority> dbAuths = new ArrayList<GrantedAuthority>(dbAuthsSet);
        
        if (dbAuths.size() == 0) {
            logger.debug("User '" + username + "' has no authorities and will be treated as 'not found'");

            throw new UsernameNotFoundException(
                    messages.getMessage("JdbcDaoImpl.noAuthority",
                            new Object[] {username}, "User {0} has no GrantedAuthority"), username);
        } else {
        	user.setAuthorities(dbAuths);
        }
        

		return user;
	}
	
	
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
	
}
